
// basic ToolbarItem, from which Button, ToggleButton, etc. inherit
Refresh.Web.ToolbarItem = {};
Refresh.Web.ToolbarItem.prototype = {
	id: '',
	command: null,
	
	initialize: function(id, command, settings, items, toolbar) {
		this.id = id;
		this.command = command;
		this.items = items;
		this.settings = settings;
		this.toolbar = toolbar;
		
		if (this._initialize != null)
			this._initialize();
			
	},

	// creates a node to attach to whatever is holding the item
	createHtmlNode: function() {
		
	},

	// sets the state based on the command checkState
	setState: function(ftb) {
		
	}	 
};

Refresh.Web.Button = Class.create();
Object.extend(Refresh.Web.Button.prototype, Refresh.Web.ToolbarItem.prototype);
Object.extend(Refresh.Web.Button.prototype, {
	
	setState: function(ftb) {		
		this._buttonState = this.command.getValue(ftb);		
		this._setButtonClass();		
	},
	
	_initialize: function() {
		this.node = Refresh.Web.HTML.create('div', {id: this.id, className: this.toolbar.settings.cssPrefix + 'toolbar_Button'});
		Refresh.Web.HTML.append(this.node, 'img', {src: Refresh.path + 'themes/' + this.toolbar.settings.theme + '/images/' + this.command.name + '.gif', alt: this.id, title: Refresh.Web.Localization.getValue(this.command.name)});	
		
		this._buttonState = FTB_BUTTONSTATE_NORMAL;
		this._isMouseOver = false;
		this._classPrefix = this.node.className;
		
		Event.observe(this.node, 'mousedown', this._onMouseDown.bindAsEventListener(this));
		Event.observe(this.node, 'mouseover', this._onMouseOver.bindAsEventListener(this));
		Event.observe(this.node, 'mouseout',  this._onMouseOut.bindAsEventListener(this));										
		
		this._onMouseOut();			
	},
	
	
	_onMouseOver : function(event) {
		this._isMouseOver = true;

		this._setButtonClass();		
	},
	
	_onMouseDown : function(event) {	
		if (this._buttonState = FTB_BUTTONSTATE_DISABLED) return;
		
		Event.stop(event);		
		
		this.command.execute(this.toolbar.getActiveEditor(),null,this);
				
		this._buttonState = this.command.getValue(this.toolbar.getActiveEditor());
		
		this._setButtonClass();
	},
	
	_onMouseOut : function(event) {
		this._isMouseOver = false;
		
		this._setButtonClass();
	},
	
	_setButtonClass: function() {
	
		Element.removeClassName(this.node, this._classPrefix + '_Over');
		Element.removeClassName(this.node, this._classPrefix + '_Normal');
		Element.removeClassName(this.node, this._classPrefix + '_Highlight');
		Element.removeClassName(this.node, this._classPrefix + '_Disabled');
		
		switch(this._buttonState) {
			default:
			case FTB_BUTTONSTATE_NORMAL:
				if (this._isMouseOver)
					Element.addClassName(this.node, this._classPrefix + '_Over');
				else
					Element.addClassName(this.node, this._classPrefix + '_Normal');
				
				break;

			case FTB_BUTTONSTATE_DISABLED:
				Element.addClassName(this.node, this._classPrefix + '_Disabled');
				break;

			case FTB_BUTTONSTATE_HIGHLIGHT:
				Element.addClassName(this.node, this._classPrefix + '_Highlight');
				break;
		}	
	}
});

// different main class
Refresh.Web.GalleryButton = Class.create();
Object.extend(Refresh.Web.GalleryButton.prototype, Refresh.Web.Button.prototype);
Object.extend(Refresh.Web.GalleryButton.prototype, {
	_initialize: function() {
		this.node = Refresh.Web.HTML.create('div', {id: this.id, className: this.toolbar.settings.cssPrefix + 'toolbar_DropButton'});
		Refresh.Web.HTML.append(this.node, 'img', {src: Refresh.path + 'themes/' + this.toolbar.settings.theme + '/images/' + this.command.name + '.gif', alt: this.id});

		this._buttonState = FTB_BUTTONSTATE_NORMAL;
		this._isMouseOver = false;
		this._classPrefix = this.node.className;
		
		Event.observe(this.node, 'mousedown', this._onMouseDown.bindAsEventListener(this));
		Event.observe(this.node, 'mouseover', this._onMouseOver.bindAsEventListener(this));
		Event.observe(this.node, 'mouseout',  this._onMouseOut.bindAsEventListener(this));										
		
		this._onMouseOut();	
	}
});


Refresh.Web.ComboBox = Class.create();
Object.extend(Refresh.Web.ComboBox.prototype, Refresh.Web.ToolbarItem.prototype);
Object.extend(Refresh.Web.ComboBox.prototype, {
	
	selectedIndex: -1,
	
	_highlightedIndex: -1,
	
	_initialize: function() {
		this.node = Refresh.Web.HTML.create('div', {id: this.id, className: this.toolbar.settings.cssPrefix + 'toolbar_List'});
		
		if (!this.settings)
			this.settings = this.command.defaultSettings;
		
		if (!this.settings.listWidth)
			this.settings.listWidth = this.settings.width;
			
		this.settings.height = '16px';
		
		if (!this.items)
			this.items = this.command.defaultItems;
			
		this._display = Refresh.Web.HTML.append(this.node, 'div', {id: this.id + '_list', className: this.toolbar.settings.cssPrefix + 'comboBox_Display'}); 		
		Refresh.Web.HTML.text(this._display, this.settings.title);
		this._display.style.overflow = 'hidden';
		if (this.settings.width) this._display.style.width = this.settings.width;
		if (this.settings.height) this._display.style.height = this.settings.height;

		// draw dropdownbox on document
		this._listHolder = Refresh.Web.HTML.append(document.body, 'div', {id: this.id + '_DropDownContainer', className: this.toolbar.settings.cssPrefix + 'comboBox_List'});
		this._listHolder.style.visibility = 'hidden';
		this._listHolder.style.position =  'absolute';
		this._listHolder.style.overflow = 'auto';
		this._listHolder.style.textAlign = 'left';
		this._listHolder.style.left = '-1000px';
		this._listHolder.style.width = this.settings.listWidth;
		
		this._list = Refresh.Web.HTML.append(this._listHolder, 'ul');

		// add list items
		for (var i=0; i<this.items.length; i++) {
			var listItem = this.items[i];
			if (listItem == null) break;

			var item = Refresh.Web.HTML.append(this._list, 'li', {className: this.toolbar.settings.cssPrefix + 'comboBox_Item'} );
			item.innerHTML = (listItem.display) ? listItem.display : listItem.text;
			item.value = listItem.value;
			item.index = i;			
								
		    Event.observe(item, 'mouseover',this._onItemOver.bindAsEventListener(this));
			Event.observe(item, 'mouseout', this._onItemOut.bindAsEventListener(this));
		    Event.observe(item, 'click',    this._onItemClick.bindAsEventListener(this));	
		}
		
		
		//Refresh.Utility.makeUnselectable(this._display);
		//Refresh.Utility.makeUnselectable(this._list);
				
		// attach events to main display
		Event.observe(this._display, 'mouseover',this._onMouseOver.bindAsEventListener(this));
		Event.observe(this._display, 'mouseout', this._onMouseOut.bindAsEventListener(this));
		Event.observe(this._display, 'click',this._onClick.bindAsEventListener(this));
		
		this._docClickListener = this._onDocClick.bindAsEventListener(this);	
	},	
	
	_onMouseOver: function(event) {
		Element.addClassName(this._display,this.toolbar.settings.cssPrefix + 'comboBox_Display_Over');
	},
	
	_onMouseOut: function(event) {
		
		
		if (this._list.style.visibility != 'visible') {
			Element.removeClassName(this._display,this.toolbar.settings.cssPrefix + 'comboBox_Display_Over');
		}
	},	
	
	_onClick: function(event) {
		Event.stop(event);
		this.toggle();	
	},	
	
	_onItemClick: function(event) {
		Event.stop(event);
		var listItem = Event.findElement(event, 'LI');
		this.selectedIndex = listItem.index;	
		
		var item = this.items[listItem.index];

		this.command.execute(this.toolbar.getActiveEditor(), item.value);
		
		this.hide();
	},
	
	_setSelected: function() {
		this.selectedItem = this.items[this.selectedIndex];
		Refresh.Web.HTML.text(this._display, this.selectedItem.text);
		this.hide();
	},

	_onItemOver: function(event) {
		var item = Event.findElement(event, 'LI');
		this._highlightedIndex = item.index;
		this._doHighlight();
		//Element.addClassName(item, 'comboBox_Item_Over');
	},

	_onItemOut: function(event) {
		var item = Event.findElement(event, 'LI');
		this.highlightedIndex = -1;
		this._doHighlight();
		//Element.removeClassName(item, 'comboBox_Item_Over');
	},

	_onDocClick: function(event) {
		var clickedOut = true;
		var x = Event.pointerX(event);
		var y = Event.pointerY(event);

		clickedOut = !Position.within(this._list, x, y);
		if (clickedOut)
			clickedOut = !Position.within(this._listHolder,x, y);
		
		if (clickedOut) {
			this.hide();			
			Event.stopObserving(document, 'click', this._docClickListener);
			Event.stopObserving(this.toolbar.getActiveEditor()._getDocument(), 'click', this._docClickListener);
		}
	},		
	
	_doHighlight: function() {
		for (var i=0; i<this.items.length; i++) {
			var li = this._list.childNodes[i];
			if (i == this._highlightedIndex) {
				Element.addClassName(li, this.toolbar.settings.cssPrefix + 'comboBox_Item_Over');
			} else {
				Element.removeClassName(li, this.toolbar.settings.cssPrefix + 'comboBox_Item_Over');
			}
		}
	},
	
	_setDropDownPosition: function() {
		
		var boxPos = this.positionedOffset(this._display);
		//var boxPos = Position.cumulativeOffset(this._display); // .positionedOffset(this._display);
		
		
		var boxSize = Element.getDimensions(this._display);
		
		
		this._listHolder.style.left = boxPos[0] + 'px';
		this._listHolder.style.top = (boxPos[1] + boxSize.height - 1) + 'px';		
		
		// put on top of the highest element
		if (boxPos[2] && boxPos[2].style.zIndex > 1)
			this._listHolder.style.zIndex = boxPos[2].style.zIndex+1;
	},	

	// CHANGED FROM prototype.js to work for floaties
	positionedOffset: function(element) {
		var valueT = 0, valueL = 0;
		do {
		  valueT += element.offsetTop  || 0;
		  valueL += element.offsetLeft || 0;
		  element = element.offsetParent;
		  if (element) {		  	
			if(element.tagName=='BODY') break;	        		
			var p = Element.getStyle(element, 'position');
			if (p == 'relative') break;	
			if (p == 'absolute') {
				valueT += element.offsetTop  || 0;
				valueL += element.offsetLeft || 0;
				break;
			}
		  }
		} while (element);
		return [valueL, valueT, element];
	},	
		
	setValue: function(value) {
		if (value == null || value == '') {
			this.selectedIndex = -1;
			Refresh.Web.HTML.text(this._display, this.settings.title);
		} else {
			for (var i=0; i<this.items.length; i++) {
				if (this.items[i].value.toLowerCase() == value.toLowerCase()) {
					this.selectedIndex = i;
					this._setSelected();
					break;
				}
			}	
		}
	},

	show: function() {
		this._setDropDownPosition();

		this._listHolder.style.visibility = 'visible';
		
		// bind document click to hide		
		Event.observe(document, 'click', this._docClickListener);
		
		// bind to editor for clicking on editor document
		Event.observe(this.toolbar.getActiveEditor()._getDocument(), 'click', this._docClickListener);	

		this.toolbar.visibleElement = this._listHolder;
	},	
	
	getValue: function() {
		return this.items[this.selectedIndex].value;			
	},

	hide: function() {	
	
		this._listHolder.style.visibility = 'hidden';
		this._listHolder.style.left = '-1000px';
		Element.removeClassName(this._display,this.toolbar.settings.cssPrefix + 'comboBox_Display_Over');
		
		this.toolbar.visibleElement = null;
	},

	toggle: function() {
		if (this._list.style.visibility == 'visible') {
			this.hide();
		} else {
			this.show();
		}
	},

	setState: function(ftb) {	
		//
		this.hide();
		this.setValue( this.command.getValue( ftb ) );
	}		

});